package org.example.services.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.example.Exception.RollBackException;
import org.example.SpringSecurityTestApplication;
import org.example.constant.RoleEnum;
import org.example.dao.RoleDao;
import org.example.dao.UserDao;
import org.example.domain.PageBean;
import org.example.domain.Role;
import org.example.domain.User;
import org.example.domain.response.ResponseResult;
import org.example.services.UserService;
import org.example.utils.FileUtil;
import org.example.utils.RsaUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.util.ListUtils;

import javax.annotation.Resource;
import java.beans.Encoder;
import java.io.File;
import java.io.IOException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
@Transactional
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao userDao;
    @Resource
    private RoleDao roleDao;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Value("${user.defaultPassword}")
    private String defaultPassword;
    @Value("${user.defaultAvatar}")
    private String defaultAvatar;

    @Override
    public ResponseResult getUserById(int userId) {
        try {
            User user = userDao.selectById(userId);
            if(user == null){
                log.info("通过ID查询用户：该用户ID不存在");
                return ResponseResult.failed("该用户不存在");
            }
            String role = userDao.getRoleByUserId(userId);
            user.setRole(role);
            log.info("通过ID查询用户：查询用户{}:{}成功",user.getUserId(),user.getUsername());
            return ResponseResult.success("查询用户成功",user);
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("通过用户DI查询用户：失败");
            return ResponseResult.failed("查询用户失败");
        }
    }

    @Override
    public ResponseResult saveUser(User user) {
        try {
            String encodeDefaultPassword = passwordEncoder.encode(defaultPassword);
            userDao.insert(user);
            userDao.updatePasswordById(user.getUserId(),encodeDefaultPassword);
            if (user.getRole() == null) {
                userDao.insertUserRole(user.getUserId(), RoleEnum.User.getRoleId());
            }else{
                userDao.insertUserRole(user.getUserId(), userDao.getRoleIdByRoleKey(user.getRole()));
            }
            ResponseResult userRes = getUserById(user.getUserId());
            log.info("管理员添加用户：成功{}",userRes.getData());
            return ResponseResult.success("用户添加成功",userRes.getData());
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("管理员新增用户：失败");
            throw new RollBackException("新增失败");
        }
    }

    @Override
    public ResponseResult resetPasswordById(int userId) {
        try {
            User user = userDao.selectById(userId);
            if(user == null){
                log.info("通过ID查询用户：该用户ID不存在");
                return ResponseResult.failed("该用户不存在");
            }
            String encodeDefaultPassword = passwordEncoder.encode(defaultPassword);
            userDao.updatePasswordById(user.getUserId(),encodeDefaultPassword);
            log.info("管理员重置用户{}密码{}：成功",userId,defaultPassword);
            return ResponseResult.success("用户密码重置成功",null);
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("管理员重置用户{}密码：失败",userId);
            throw new RollBackException("用户密码重置失败");
        }
    }

    @Override
    public ResponseResult deleteUserById(int userId) {
        try {
            User user = userDao.selectById(userId);
            if(user == null){
                log.info("通过ID删除用户：用户不存在");
                return ResponseResult.failed("无该用户信息，请刷新重试");
            }
            userDao.deleteById(userId);
            log.info("通过ID删除用户：删除成功");
            return ResponseResult.success("用户删除成功",null);
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("通过ID删除用户：失败");
            return ResponseResult.failed("删除用户失败");
        }
    }

    @Override
    public ResponseResult updateUser(User user) {
        try {
            User userRes = userDao.selectById(user.getUserId());
            if(userRes == null){
                log.info("修改用户信息：无{}用户信息",user.getUserId());
                return ResponseResult.failed("用户信息不存在");
            }
            userDao.updateById(user);
            userDao.updateUserRole(user.getUserId(), userDao.getRoleIdByRoleKey(user.getRole()));
            log.info("修改用户信息：修改成功");
            return ResponseResult.success("用户修改成功",null);
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("修改用户信息：修改失败");
            return ResponseResult.failed("用户修改失败");
        }
    }

    @Override
    public ResponseResult getUserByPage(int currentPage, int pageSize) {
        try {
            Page<User> userPage = new Page<>();
            userPage.setCurrent(currentPage);
            userPage.setSize(pageSize);
            userDao.selectPage(userPage,null);
            PageBean<User> userPageRes = new PageBean<>();
            userPageRes.setCurrentPage((int) userPage.getCurrent());
            userPageRes.setPageSize((int) userPage.getSize());
            userPageRes.setTotalPages((int) userPage.getPages());
            userPageRes.setTotalData((int) userPage.getTotal());

            List<User> rows = userPage.getRecords();
            for (User row : rows) {
                String role = userDao.getRoleByUserId(row.getUserId());
                row.setRole(role);
            }
            userPageRes.setRows(rows);
            log.info("分页查询用户：成功{}",userPageRes);
            return ResponseResult.success("分页查询用户成功",userPageRes);
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("分页查询用户：失败");
            return ResponseResult.failed("分页查询失败");
        }
    }

    @Override
    public ResponseResult getUserByUsername(int currentPage, int pageSize, String username) {
        try {
            Page<User> userPage = new Page<>(currentPage,pageSize);
            LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.like(User::getUsername,username);
            userDao.selectPage(userPage,lambdaQueryWrapper);
//            if(ListUtils.isEmpty(userPage.getRecords())){
//                log.info("通过用户名分页查询：无满足条件用户");
//                return ResponseResult.success("无满足条件用户",null);
//            }
            PageBean<User> userPageRes = new PageBean<>();
            userPageRes.setCurrentPage((int) userPage.getCurrent());
            userPageRes.setPageSize((int) userPage.getSize());
            userPageRes.setTotalPages((int) userPage.getPages());
            userPageRes.setTotalData((int) userPage.getTotal());
            List<User> rows = userPage.getRecords();
            for (User row : rows) {
                String role = userDao.getRoleByUserId(row.getUserId());
                row.setRole(role);
            }
            userPageRes.setRows(rows);
            log.info("通过用户名分页查询用户：成功{}",userPageRes);
            return ResponseResult.success("通过用户名分页查询用户成功",userPageRes);
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("通过用户名分页查询用户：失败");
            return ResponseResult.failed("通过用户名分页查询失败");
        }
    }

    @Override
    public ResponseResult updateUserPassword(int userId, String encryptPassword, String encryptNewPassword) {
        try {
            User userRes = userDao.selectById(userId);
            if(userRes == null){
                log.info("修改用户密码：无{}用户信息",userId);
                return ResponseResult.failed("用户信息不存在");
            }
            String deCryptPassword = RsaUtils.decryptByPrivateKey(encryptPassword);
            log.info("密码解密后的明文：{}",deCryptPassword);
            String passwordFromData = userDao.getPasswordById(userId);
            boolean flag = passwordEncoder.matches(deCryptPassword, passwordFromData);
            if(!flag){
                log.info("修改用户密码：旧密码错误");
                return ResponseResult.failed("旧密码错误，请核对后再试");
            }

            String deCryptNewPassword = RsaUtils.decryptByPrivateKey(encryptNewPassword);
            String encodePassword = passwordEncoder.encode(deCryptNewPassword);
            userDao.updatePasswordById(userId,encodePassword);
            log.info("修改用户密码：修改成功");
            return ResponseResult.success("密码修改成功",null);
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("修改用户密码：修改失败");
            return ResponseResult.failed("修改用户密码失败");
        }
    }

    @Override
    public ResponseResult uploadIcon(MultipartFile file, int userId) {
        User user = userDao.selectById(userId);
        if(user == null){
            return ResponseResult.failed("用户不存在，请刷新后重试");
        }
        ApplicationHome applicationHome = new ApplicationHome(SpringSecurityTestApplication.class);
        //将文件保存在当前项目同目录中的images中
        //打包前是当前java文件目录下，打包后是在项目目录下
        String path = applicationHome.getDir().getAbsolutePath()
                + File.separator  + "images"
                + File.separator  + "avatar";

        if(file.isEmpty()){
            return ResponseResult.failed("文件为空");
        }
        String fileName = file.getOriginalFilename();
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
//        log.info("文件路径：" + path);
//        log.info("上传的文件名为：" + fileName + "，后缀名：" + suffixName);
//        //按照 用户ID：uuid(去除-).后缀
//        String fileNameNew = UUID.randomUUID().toString().replace("-","") + suffixName;
//        log.info("重命名后的文件名为：" + fileNameNew + "，后缀名：" + suffixName);
//        //判断图片文件后缀
//        if (!FileUtil.checkImageSuffix(suffixName)) {
//            return ResponseResult.failed("文件格式必须为图片");
//        }
//
//        File fileTemObj = new File(path + File.separator + fileNameNew);
//        //判断目录是否存在
//        if(!fileTemObj.getParentFile().exists()){
//            fileTemObj.getParentFile().mkdirs();
//        }
//        //判断是否有同名的文件存在
////        if(fileTemObj.exists()){
////            return ResponseResult.failed("文件已经存在");
////        }
//        try {
//            file.transferTo(fileTemObj);
//        } catch (IOException e) {
//            e.printStackTrace();
//            return ResponseResult.failed("文件上传失败");
//        }
        //修改数据库中用户的头像的
        String fileNameNew = UUID.randomUUID().toString().replace("-", "") + suffixName;
        if (!FileUtil.uploadImage(file,path,fileNameNew)) {
            log.warn("头像上传失败");
            return ResponseResult.failed("头像上传失败");
        }

        //删除原来的图片
        String icon1 = user.getIcon();
        String fileNameOld = icon1.substring(icon1.lastIndexOf(File.separator) + 1);
        if (!defaultAvatar.equals(fileNameOld)) {
            //当旧头像不是默认的头像，才删除
            int flag = FileUtil.deleteFile(path, fileNameOld);
            if( flag == 0){
                log.warn("头像图片删除失败");
                FileUtil.deleteFile(path,fileNameNew);
                return ResponseResult.failed("头像更新失败，原图删除失败");
            }
            log.info("删除文件{}成功",fileNameOld);
        }
        //保存相对路径 /images/avatar/aa.jpg
        String icon = File.separator  + "images"
                + File.separator  + "avatar"
                + File.separator + fileNameNew;
        try {
            User user1 = new User();
            user1.setUserId(userId);
            user1.setIcon(icon);
            userDao.updateById(user1);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RollBackException("修改用户头像失败");
        }
        user.setIcon(icon);
        return ResponseResult.success("文件上传成功",user);
    }

    @Override
    public ResponseResult getAvatarUserId(List<Integer> userIds) {
        ArrayList<User> users = new ArrayList<>();
        log.info("通过用户ID获取头像");
        for (Integer userId : userIds) {
            User user = userDao.selectById(userId);
            if(user == null){
                user = new User();
                user.setUserId(0);
                user.setUsername("");
                user.setIcon("");
            }
            users.add(user);
            user.setPlus(null);
            user.setRole(null);
            user.setMail(null);

        }
        return ResponseResult.success("获取成功",users);
    }
}
